//
//  ViewController.m
//  UI21_Block
//
//  Created by Scott on 16/4/7.
//  Copyright © 2016年 Scott. All rights reserved.
//

#import "ViewController.h"

/** 函数的声明. */
int sum(int, int);

/** 函数的实现. */
int sum(int x, int y) {
    
    return x + y;
}



@interface ViewController ()

// 声明Block属性, 语义设置使用copy, copy到堆区, 防止野指针.
@property (nonatomic, copy) NSString *(^handleString)(NSString *, NSString *);


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self reviewFunction];
    [self chapterOfBlock];
    
    [self defineBlock];
    [self invokeBlock];
}

#pragma mark - 复习函数
- (void)reviewFunction {
    
    // 函数的调用.
    int sumTwoInt = sum(3, 5);
    printf("sum:%d\n", sumTwoInt);
    
    // 函数指针.(技巧: 函数声明部分, 把函数名换成 (*p) );
    // 指针类型: int (*)(int, int)
    // 指针变量: p
    // 值: NULL
    int (*p)(int, int) = NULL;

    p = sum;
    
    // 通过函数指针调用函数.
    int sumTwo = p(3, 5);
    printf("sumTwo:%d\n", sumTwo);
    
}

#pragma mark - 知识点:Block
/** 
 * Block(块), 在其它编程语言中也有相似的概念,叫闭包(closure)
 *
 * Block和函数指针非常相似(技巧:将(*p) 换成(^blcok))
 *
 * Block本质是匿名函数.
 */
- (void)chapterOfBlock {
    
    // 声明一个block变量.
    // 变量类型: int (^)(int, int)
    // 变量名: handler
    int (^handler)(int, int) = NULL;
    
    
    // 赋值, 因为Block是匿名函数, 不能直接赋函数名, 直接赋实现部分.
    handler = ^(int x, int y){
        
        return x + y;
    };
    
    // 调用Block
    int sumOfHandler = handler(3, 5);
    printf("sumOfHandler:%d\n", sumOfHandler);
    
    
    // 定义一个求两个整数乘积的Block
    int (^handleMul)(int, int) = ^(int x, int y) {
        
        return x * y;
    };
    
    int mul = handleMul(3, 5);
    printf("mul:%d\n", mul);
    
    
    // 定义一个拼接连个字符串的Block, (返回拼接之后的字符串)
    
    NSString * (^handlerString)(NSString *, NSString *) = ^(NSString *str1, NSString *str2) {
      
        return [str1 stringByAppendingString:str2];
        
    };
    
    NSLog(@"%@", handlerString(@"Da", @"Lian"));
    
}


/** 定义Block. */
- (void)defineBlock {

    // 属性赋值.
    self.handleString = ^(NSString *str1, NSString *str2){
        
        return [str1 stringByAppendingString:str2];
    };
}

/** 调用Block. */
- (void)invokeBlock {
    
    NSString *str = self.handleString(@"Da", @"Lian");
    
    NSLog(@"str:%@",str);
    
}

#pragma mark -
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
